package ar.edu.caece.dns.modelo.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import org.apache.log4j.Logger;

import ar.edu.caece.dns.modelo.servidor.Request;
import ar.edu.caece.dns.modelo.servidor.Response;
import ar.edu.caece.dns.modelo.servidor.Servidor;

/**
 * Esta clase se encarga de trabajar con el socket de un cliente. Lo abre para
 * leer el requerimiento, se lo pasa al servidor dns y escribe el resultado.
 * 
 * @author Lucas Jun 19, 2012 - 7:44:26 PM
 */
public class RequestController {

	private static final boolean AUTO_FLUSH = true;

	private final Logger logger = Logger.getLogger(this.getClass());

	private Socket socket;

	private Servidor servidor;

	private PrintWriter outputStream;

	private BufferedReader inputStream;

	public Socket getSocket() {
		return socket;
	}

	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	public Servidor getServidor() {
		return servidor;
	}

	public void setServidor(Servidor servidor) {
		this.servidor = servidor;
	}

	/**
	 * Abre los streams de conexion del socket
	 * 
	 * @throws IOException
	 */
	public void init() throws IOException {
		OutputStream socketOut = socket.getOutputStream();
		InputStream socketIn = socket.getInputStream();

		outputStream = new PrintWriter(socketOut, AUTO_FLUSH);
		inputStream = new BufferedReader(new InputStreamReader(socketIn));
	}

	/**
	 * Cierra la comunicacion con el socket
	 * 
	 * @throws IOException
	 */
	public void close() throws IOException {

		if (outputStream != null)
			outputStream.close();

		if (inputStream != null)
			inputStream.close();

		if (socket != null)
			socket.close();

	}

	/**
	 * Lee el request del socket, prepara la invocacion al servidor dns y espera
	 * la respuesta, por ultimo la escribe al cliente y cierra conexiones.
	 */
	public void dispatch() {
		Request request = null;
		Response response = null;

		try {
			this.init();

			request = new Request(inputStream.readLine());
			response = servidor.service(request);

			outputStream.println(response);

		} catch (IOException ioe) {
			logger.error("Error de comunicacion con cliente", ioe);

		} finally {

			try {
				this.close();

			} catch (IOException ioe) {
				logger.error("Error al cerrar comunicacion con cliente", ioe);

			}
		}
	}
}
